package slideWindow;

/**
 * @author pengfei.hpf
 * @date 2020/3/10
 * @verdion 1.0.0
 * 424. 替换后的最长重复字符
 * 给你一个仅由大写英文字母组成的字符串，你可以将任意位置上的字符替换成另外的字符，总共可最多替换 k 次。在执行上述操作后，找到包含重复字母的最长子串的长度。
 *
 * 注意:
 * 字符串长度 和 k 不会超过 104。
 *
 * 示例 1:
 *
 * 输入:
 * s = "ABAB", k = 2
 *
 * 输出:
 * 4
 *
 * 解释:
 * 用两个'A'替换为两个'B',反之亦然。
 * 示例 2:
 *
 * 输入:
 * s = "AABABBA", k = 1
 *
 * 输出:
 * 4
 *
 * 解释:
 * 将中间的一个'A'替换为'B',字符串变为 "AABBBBA"。
 * 子串 "BBBB" 有最长重复字母, 答案为 4。
 */
public class CharacterReplacement {

    public int characterReplacement(String s, int k) {
        if(s == null || s.length() == 0){
            return 0;
        }
        char[] chars = s.toCharArray();
        int left = 0;
        int right = 1;
        int maxCur = 1;
        int maxChar = chars[0] - 'A';
        int size = 1;
        int res = 1;
        int[] records = new int[26];
        records[maxChar]++;
        while(right < chars.length){
            int c = chars[right] - 'A';
            records[c] ++;
            size ++;
            if(records[c] > maxCur){
                maxCur = records[c];
                maxChar = c;
            }
            if(size <= maxCur + k){
                res = Math.max(res, size);
            }
            //TODO: 滑动窗口左边收缩的条件, 直到要满足条件才退出
            while(size > maxCur + k){
                int c2 = chars[left] - 'A';
                if(records[c2] > maxCur){
                    maxCur = records[c2];
                    maxChar = chars[left];
                } else {
                    left ++;
                    records[c2]--;
                    size --;
                    if(chars[left] == maxChar){
                        maxCur --;
                    }
                }
            }
            right ++;
        }
        return res;
    }
}
